home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / system / mail / transpor / ifmail23.z / ifmail23 / ifmail / ifgate / mkrfcmsg.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-05-10  |  12.4 KB  |  526 lines

  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <sys/types.h>
  5. #include <sys/stat.h>
  6. #include <time.h>
  7. #include "lutil.h"
  8. #include "xutil.h"
  9. #include "mkrfcmsg.h"
  10. #include "rfcmsg.h"
  11. #include "areas.h"
  12. #include "falists.h"
  13. #include "config.h"
  14.  
  15. #define BOUNDARY 79
  16.  
  17. int num_echo=0,num_mail=0;
  18. extern char *version;
  19. extern FILE *nb;
  20. extern faddr pktfrom;
  21.  
  22. extern char *rfcdate(time_t);
  23. extern long sequencer(void);
  24. extern char *lookup(char *);
  25. extern char *backalias(faddr *);
  26.  
  27. char *rfcmsgid(msgid)
  28. char *msgid;
  29. {
  30.     static char buf[128],*p,*q;
  31.     unsigned long id=0L;
  32.     faddr *ta=NULL;
  33.  
  34.     if ((p=strrchr(msgid,' ')))
  35.     {
  36.         *p='\0';
  37.         sscanf(p+1,"%lx",&id);
  38.         ta=parsefnode(msgid);
  39.         *p=' ';
  40.     }
  41.     if (id != 0L)
  42.     {
  43.         if (ta)
  44.         {
  45.             sprintf(buf,"<%lu@%s>",id,ascinode(ta,0x1f));
  46.         }
  47.         else
  48.         {
  49.             p=xstrcpy(msgid);
  50.             if ((q=strchr(p,' '))) *q='\0';
  51.             sprintf(buf,"<%lu@%s>",id,p);
  52.             free(p);
  53.         }
  54.     }
  55.     else
  56.     {
  57.         sprintf(buf,"<%lu@%s>",sequencer(),
  58.             ascinode(whoami->addr,0x1f));
  59.     }
  60.     tidy_faddr(ta);
  61.     return buf;
  62. }
  63.  
  64. /* check address for localness, substitute alises and replace it *in place* */
  65.  
  66. void substitute(buf)
  67. char *buf;
  68. {
  69.     faddr *fa;
  70.     char *l,*r,*p=NULL;
  71.     int inquotes,inbrackets;
  72.  
  73.     debug(6,"to address before subst: \"%s\"",buf);
  74.     if ((l=strchr(buf,'<')) && (r=strchr(buf,'>')) && (l < r))
  75.     {
  76.         l++;
  77.         *r='\0';
  78.     }
  79.     else l=buf;
  80.     while (*l == ' ') l++;
  81.     for (r=l,inquotes=0,inbrackets=0;*r;r++) switch (*r)
  82.     {
  83.     case '"':    inquotes=(!inquotes); break;
  84.     case ',':
  85.     case ' ':    if (!inquotes && !inbrackets) *r='\0'; break;
  86.     case '(':    if (!inquotes) inbrackets++; break;
  87.     case ')':    if (!inquotes && inbrackets) inbrackets--; break;
  88.     default:    break;
  89.     }
  90.     if ((fa=parsefaddr(l)))
  91.     {
  92.         if (is_local(fa))
  93.         {
  94.             sprintf(buf,"%s",fa->name);
  95.             if (!strchr(buf,'@') && (p=strrchr(buf,'%')))
  96.                 *p='@';
  97.             if (!strchr(buf,'@'))
  98.             {
  99.                 if ((p=lookup(buf)))
  100.                     strcpy(buf,p);
  101.                 else for (p=buf;*p;p++)
  102.                     if (*p == ' ') *p='.';
  103.             }
  104.             if (!strcasecmp(buf,"sysop")) strcpy(buf,"postmaster");
  105.         }
  106.         else
  107.         {
  108.             sprintf(buf,"%s",ascinode(fa,0x7f));
  109.         }
  110.         tidy_faddr(fa);
  111.     }
  112.     else 
  113.     {
  114.         for (r=buf;*l;l++,r++) *r=*l;
  115.         *(r+1)='\0';
  116.     }
  117.     if (buf[0] == '\0') strcpy(buf,"postmaster");
  118.     debug(6,"to address after  subst: \"%s\"",buf);
  119.     return;
  120. }
  121.  
  122. static char *flnm[] = {
  123.         "PVT","CRS","RCV","SNT","ATT","TRN","ORP","K/S",
  124.         "LOC","HLD","RSV","FRQ","RRQ","RRC","ARQ","FUP"
  125. };
  126.  
  127. /* from, to, subj, orig, mdate, flags, file, offset, kluges */
  128.  
  129. int mkrfcmsg(f,t,subj,orig,mdate,flags,fp,endoff,kmsg)
  130. faddr *f,*t;
  131. char *subj,*orig;
  132. time_t mdate;
  133. int flags;
  134. FILE *fp;
  135. off_t endoff;
  136. rfcmsg *kmsg;
  137. {
  138.     char buf[BUFSIZ];
  139.     char cmd[BUFSIZ];
  140.     char *p,*l,*r,*b;
  141.     char *newsgroup=NULL,*distribution=NULL;
  142.     char c;
  143.     int count,i,rrq;
  144.     rfcmsg *msg=NULL,*tmsg;
  145.     FILE *pip;
  146.     struct stat stbuf;
  147.     int newsmode,pass,rc;
  148.     faddr *ta;
  149.     fa_list *ftnpath=NULL,*tfa;
  150.     time_t now;
  151.     int lines;
  152.     char lineshdr[16];
  153.  
  154.     msg=parsrfc(fp);
  155.  
  156.     if (kmsg && !strcmp(kmsg->key,"AREA"))
  157.     {
  158.         ngdist(kmsg->val,&newsgroup,&distribution);
  159.         if (!newsgroup)
  160.         {
  161.             tidyrfc(msg);
  162.             return 0;
  163.         }
  164.         newsmode=1;
  165.     }
  166.     else newsmode=0;
  167.     debug(5,"Got %s message",newsmode?"echo":"netmail");
  168.  
  169.     if ((p=hdr("INTL",kmsg)))
  170.     {
  171.         strncpy(buf,p,sizeof(buf)-1);
  172.         l=strtok(buf," \n");
  173.         r=strtok(NULL," \n");
  174.         if ((ta=parsefnode(l)))
  175.         {
  176.             t->point=ta->point;
  177.             t->node=ta->node;
  178.             t->net=ta->net;
  179.             t->zone=ta->zone;
  180.             if (ta->domain)
  181.             {
  182.                 if (t->domain) free(t->domain);
  183.                 t->domain=ta->domain;
  184.                 ta->domain=NULL;
  185.             }
  186.             tidy_faddr(ta);
  187.         }
  188.         if ((ta=parsefnode(r)))
  189.         {
  190.             f->point=ta->point;
  191.             f->node=ta->node;
  192.             f->net=ta->net;
  193.             f->zone=ta->zone;
  194.             if (ta->domain)
  195.             {
  196.                 if (f->domain) free(f->domain);
  197.                 f->domain=ta->domain;
  198.                 ta->domain=NULL;
  199.             }
  200.             tidy_faddr(ta);
  201.         }
  202.     }
  203.  
  204.     if ((p=hdr("FMPT",kmsg))) f->point=atoi(p);
  205.     if (f->domain == NULL) f->domain=xstrcpy(whoami->addr->domain);
  206.     if ((p=hdr("TOPT",kmsg))) t->point=atoi(p);
  207.     if (t->domain == NULL) t->domain=xstrcpy(whoami->addr->domain);
  208.  
  209.     if (!newsmode)
  210.     {
  211.         p=hdr("Resend-To",msg);
  212.         if (p == NULL) p=hdr("To",msg);
  213.         if (p == NULL) p=hdr("RFC-Resend-To",kmsg);
  214.         if (p == NULL) p=hdr("RFC-To",kmsg);
  215.         if (p)
  216.         {
  217.             while (*p == ' ') p++;
  218.             strncpy(buf,p,sizeof(buf)-1);
  219.             if (*(p=buf+strlen(buf)-1) == '\n') *p='\0';
  220.         }
  221.         else sprintf(buf,"%s",ascinode(t,0x7f));
  222.         substitute(buf);
  223.         loginf("mail from %s to %s",ascfnode(f,0x7f),buf);
  224.     }
  225.  
  226.     if ((newsmode) && (nb == NULL))
  227.     {
  228.         if (verbose) nb=fopen(tempnam("/tmp/ifmail","N."),"w");
  229.         else nb=popen(rnews,"w");
  230.         if (nb == NULL)
  231.         {
  232.             logerr("$Could non open (pipe) output for news");
  233.             tidyrfc(msg);
  234.             return 2;
  235.         }
  236.     }
  237.  
  238.     if (newsmode)
  239.     {
  240.         if ((pip=tmpfile()) == NULL)
  241.         {
  242.             logerr("$Cannot open second temporary file");
  243.             tidyrfc(msg);
  244.             return 2;
  245.         }
  246.     }
  247.     else
  248.     {
  249.         sprintf(cmd,"%s %s",sendmail,buf);
  250.         debug(2,"popen(\"%s\",\"w\")",cmd);
  251.         if (verbose) pip=fopen(tempnam("/tmp/ifmail","M."),"w");
  252.         else pip=popen(cmd,"w");
  253.         if (pip == NULL)
  254.         {
  255.             logerr("$Could non open (pipe) output for mail");
  256.             tidyrfc(msg);
  257.             return 2;
  258.         }
  259.     }
  260.  
  261.  
  262.     if (newsmode)
  263.     {
  264.         num_echo++;
  265.         fill_list(&ftnpath,hdr("PATH",kmsg));
  266.         fprintf(pip,"Path: ");
  267.         
  268.         fprintf(pip,"%s!",ascinode(whoami->addr,0x07));
  269.         fprintf(pip,"%s!",ascinode(&pktfrom,0x07));
  270.         if (ftnpath)
  271.             for (tfa=ftnpath->next;tfa;tfa=tfa->next)
  272.                 fprintf(pip,"%s!",ascinode(tfa->addr,0x06));
  273.         else
  274.         {
  275.             fprintf(pip,"%s!",ascinode(f,0x07));
  276.         }
  277.         tidy_falist(&ftnpath);
  278.         if ((p=hdr("Path",msg)) == NULL)
  279.             p=hdr("RFC-Path",kmsg);
  280.         if (p)
  281.         {
  282.             while (*p == ' ') p++;
  283.             fprintf(pip,"%s",p);
  284.         }
  285.         else fprintf(pip,"%s\n",ascinode(f,0x40));
  286.  
  287.         fprintf(pip,"Newsgroups: %s\n",newsgroup);
  288.         if (distribution)
  289.             fprintf(pip,"Distribution: %s\n",distribution);
  290.         if (t->name == NULL) t->name=xstrcpy("All");
  291.         p=hdr("Comment-To",msg);
  292.         if (p == NULL) p=hdr("X-Comment-To",msg);
  293.         if (p == NULL) p=hdr("To",msg);
  294.         if (p)
  295.             fprintf(pip,"X-Comment-To:%s",p);
  296.         else
  297.         {
  298.             if (p == NULL) p=hdr("RFC-X-Comment-To",kmsg);
  299.             if (p == NULL) p=hdr("RFC-Comment-To",kmsg);
  300.             if (p == NULL) p=hdr("RFC-To",kmsg);
  301.             if (p) fprintf(pip,"X-Comment-To: %s",p);
  302.             else fprintf(pip,"X-Comment-To: %s\n",ascinode(t,0xff));
  303.         }
  304.     }
  305.     else
  306.     {
  307.         num_mail++;
  308.         time(&now);
  309. #ifdef NEED_UUCPFROM
  310.         fprintf(pip,"From %s!",ascinode(f,0x3f));
  311.         fprintf(pip,"%s %s",ascinode(f,0x40),ctime(&mdate));
  312. #endif
  313.         fprintf(pip,"Received: from %s ",ascinode(f,0x3f));
  314.         fprintf(pip,"by %s\n",ascinode(bestaka_s(f),0x3f));
  315.         fprintf(pip,"\twith FTN (ifmail v.%s) id AA%u; %s\n",
  316.             version,getpid(),rfcdate(now));
  317.         for (tmsg=msg;tmsg;tmsg=tmsg->next)
  318.             if (!strcasecmp(tmsg->key,"Received"))
  319.                 fprintf(pip,"%s:%s",tmsg->key,tmsg->val);
  320.         if (hdr("Apparently-To",msg) == NULL)
  321.             fprintf(pip,"Apparently-To: %s\n",buf);
  322.         if (t->name == NULL) t->name=xstrcpy("Sysop");
  323.         p=hdr("Resend-To",msg);
  324.         if (p == NULL) p=hdr("To",msg);
  325.         if (p)
  326.             fprintf(pip,"To:%s",p);
  327.         else
  328.         {
  329.             if (p == NULL) p=hdr("RFC-Resend-To",kmsg);
  330.             if (p == NULL) p=hdr("RFC-To",kmsg);
  331.             if (p) fprintf(pip,"To: %s",p);
  332.             else fprintf(pip,"To: %s\n",ascinode(t,0xff));
  333.         }
  334.     }
  335.  
  336.     if ((p=hdr("From",msg))) fprintf(pip,"From:%s",p);
  337.     else if ((p=hdr("RFC-From",kmsg))) fprintf(pip,"From: %s",p);
  338.     else fprintf(pip,"From: %s\n",ascinode(f,0xff));
  339.  
  340.     if ((p=hdr("Reply-To",msg))) fprintf(pip,"Reply-To:%s",p);
  341.     else if ((p=hdr("RFC-Reply-To",kmsg))) fprintf(pip,"Reply-To: %s",p);
  342.     else if (((p=backalias(f))) && myfqdn)
  343.         fprintf(pip,"Reply-To: %s@%s\n",p,myfqdn);
  344.     else if ((p=hdr("REPLYADDR",kmsg))) fprintf(pip,"Reply-To: %s",p);
  345.  
  346.     if ((p=hdr("Date",msg))) fprintf(pip,"Date:%s",p);
  347.     else if ((p=hdr("RFC-Date",kmsg))) fprintf(pip,"Date: %s",p);
  348.     else fprintf(pip,"Date: %s\n",rfcdate(mdate));
  349.  
  350.     if ((p=hdr("Subject",msg))) fprintf(pip,"Subject:%s",p);
  351.     else if ((p=hdr("RFC-Subject",kmsg))) fprintf(pip,"Subject: %s",p);
  352.     else if (subj && (strspn(subj," \t\n\r") != strlen(subj)))
  353.         fprintf(pip,"Subject: %s\n",subj);
  354.     else fprintf(pip,"Subject: <none>\n");
  355.  
  356.     if ((p=hdr("Message-ID",msg))) fprintf(pip,"Message-ID:%s",p);
  357.     else if ((p=hdr("RFC-Message-ID",kmsg))) fprintf(pip,"Message-ID: %s",p);
  358.     else if ((p=hdr("MSGID",kmsg))) fprintf(pip,"Message-ID: %s\n",rfcmsgid(p));
  359.     else fprintf(pip,"Message-ID: <%lu@%s>\n",mdate,
  360.             ascinode(f,0x1f));
  361.  
  362.     if (newsmode)
  363.     {
  364.         if ((p=hdr("References",msg)))
  365.             fprintf(pip,"References:%s",p);
  366.         else if ((p=hdr("RFC-References",kmsg)))
  367.             fprintf(pip,"References: %s",p);
  368.         else if ((p=hdr("REPLY",kmsg)))
  369.                 fprintf(pip,"References: %s\n",rfcmsgid(p));
  370.     }
  371.     else
  372.     {
  373.         if ((p=hdr("In-Reply-To",msg)))
  374.             fprintf(pip,"In-Reply-To:%s",p);
  375.         else if ((p=hdr("RFC-In-Reply-To",kmsg)))
  376.             fprintf(pip,"In-Reply-To: %s",p);
  377.         else 
  378.         {
  379.             if ((p=hdr("REPLY",kmsg)))
  380.                 fprintf(pip,"In-Reply-To: %s\n",rfcmsgid(p));
  381.         }
  382.     }
  383.  
  384.     if ((p=hdr("Organization",msg))) fprintf(pip,"Organization:%s",p);
  385.     else if ((p=hdr("RFC-Organization",kmsg)))
  386.         fprintf(pip,"Organization: %s",p);
  387.     else if (orig) fprintf(pip,"Organization: %s\n",orig);
  388.  
  389.     for (tmsg=msg;tmsg;tmsg=tmsg->next)
  390.     {
  391.         if (strcasecmp(tmsg->key,"X-Body-Start") &&
  392.             strcasecmp(tmsg->key,"Lines") &&
  393.             strcasecmp(tmsg->key,"Path") &&
  394.             strcasecmp(tmsg->key,"Received") &&
  395.             strcasecmp(tmsg->key,"From") &&
  396.             strcasecmp(tmsg->key,"To") &&
  397.             strcasecmp(tmsg->key,"Comment-To") &&
  398.             strcasecmp(tmsg->key,"X-Comment-To") &&
  399.             strcasecmp(tmsg->key,"Date") &&
  400.             strcasecmp(tmsg->key,"Subject") &&
  401.             strcasecmp(tmsg->key,"Reply-To") &&
  402.             strcasecmp(tmsg->key,"In-Reply-To") &&
  403.             strcasecmp(tmsg->key,"References") &&
  404.             strcasecmp(tmsg->key,"Organization") &&
  405.             strcasecmp(tmsg->key,"Newsgroups") &&
  406.             strcasecmp(tmsg->key,"Distribution") &&
  407.             strcasecmp(tmsg->key,"Message-ID"))
  408.             fprintf(pip,"%s:%s",tmsg->key,tmsg->val);
  409.     }
  410.  
  411.     if ((p=hdr("X-FTN-FLAGS",msg))) strncpy(buf,p,sizeof(buf)-(4*16)-1);
  412.     else buf[0]='\0';
  413.     if (*(p=buf+strlen(buf)-1) == '\n') *p='\0';
  414.     for (i=0;i<16;i++) if (flags & (1 << i))
  415.     {
  416.         for (p=buf;*p;p++) if (!strncasecmp(p,flnm[i],3)) break;
  417.         if (*p == '\0') sprintf(p," %s",flnm[i]);
  418.     }
  419.     if (buf[0]) fprintf(pip,"X-FTN-FLAGS:%s\n",buf);
  420.     rrq=0;
  421.     for (p=buf;*p;p++) if (!strncasecmp(p,flnm[12],3)) rrq=1;
  422.     if (rrq && !hdr("RFC-Return-Receipt-To",kmsg) && 
  423.         !hdr("Return-Receipt-To",msg))
  424.     {
  425.         if ((p=hdr("REPLYADDR",kmsg)))
  426.             fprintf(pip,"Return-Receipt-To: %s",p);
  427.         else if (((p=backalias(f))) && myfqdn)
  428.             fprintf(pip,"Reply-To: %s@%s\n",p,myfqdn);
  429.         else fprintf(pip,"Return-Receipt-To: %s\n",ascinode(f,0x7f));
  430.     }
  431.  
  432.     for (tmsg=kmsg;tmsg;tmsg=tmsg->next)
  433.     {
  434.         if (strcasecmp(tmsg->key,"INTL") &&
  435.             strcasecmp(tmsg->key,"FMPT") &&
  436.             strcasecmp(tmsg->key,"TOPT") &&
  437.             strcasecmp(tmsg->key,"REPLY") &&
  438.             strcasecmp(tmsg->key,"MSGID") &&
  439.             strcasecmp(tmsg->key,"FLAGS") &&
  440.             strcasecmp(tmsg->key,"RFC-Lines") &&
  441.             strcasecmp(tmsg->key,"RFC-Path") &&
  442.             strcasecmp(tmsg->key,"RFC-Received") &&
  443.             strcasecmp(tmsg->key,"RFC-From") &&
  444.             strcasecmp(tmsg->key,"RFC-To") &&
  445.             strcasecmp(tmsg->key,"RFC-Comment-To") &&
  446.             strcasecmp(tmsg->key,"RFC-X-Comment-To") &&
  447.             strcasecmp(tmsg->key,"RFC-Date") &&
  448.             strcasecmp(tmsg->key,"RFC-Subject") &&
  449.             strcasecmp(tmsg->key,"RFC-Reply-To") &&
  450.             strcasecmp(tmsg->key,"RFC-In-Reply-To") &&
  451.             strcasecmp(tmsg->key,"RFC-References") &&
  452.             strcasecmp(tmsg->key,"RFC-Organization") &&
  453.             strcasecmp(tmsg->key,"RFC-Newsgroups") &&
  454.             strcasecmp(tmsg->key,"RFC-Distribution") &&
  455.             strcasecmp(tmsg->key,"RFC-Message-ID"))
  456.             if (!strncmp(tmsg->key,"RFC-",4))
  457.                 fprintf(pip,"%s: %s",tmsg->key+4,tmsg->val);
  458.             else
  459.                 fprintf(pip,"X-FTN-%s: %s",tmsg->key,tmsg->val);
  460.     }
  461.  
  462.     fprintf(pip,"\n");
  463.     lines=0;
  464.     if ((p=hdr("X-Body-Start",msg)))
  465.     {
  466.         lines++;
  467.         fputs(p,pip);
  468.     }
  469.     pass=1;
  470.     count=0;
  471.     while(fgets(buf,sizeof(buf)-1,fp) && pass)
  472.     {
  473.         if (ftell(fp) > endoff)
  474.         {
  475.             debug(5,"line \"%s\" past message end %ld",
  476.                 buf,endoff);
  477.             pass=0;
  478.         }
  479.         if (pass)
  480.         {
  481.             p=buf;
  482.             b=NULL;
  483.             while ((c=*p++))
  484.             {
  485.                 switch (c)
  486.                 {
  487.                 case ' ':    b=p-1; break;
  488.                 case '\n':    b=NULL; count=0; lines++; break;
  489.                 }
  490.                 if (count++ > BOUNDARY)
  491.                 {
  492.                     if (b) 
  493.                     {
  494.                         *b='\n';
  495.                         p=b+1;
  496.                         b=NULL;
  497.                         lines++;
  498.                     }
  499.                     count=0;
  500.                 }
  501.             }
  502.             fputs(buf,pip);
  503.         }
  504.     }
  505.  
  506.     if (newsmode)
  507.     {
  508.         sprintf(lineshdr,"Lines: %d\n",lines);
  509.         rewind(pip);
  510.         fstat(fileno(pip),&stbuf);
  511.         fprintf(nb,"#! rnews %lu\n",stbuf.st_size+strlen(lineshdr));
  512.         while (fgets(buf,sizeof(buf)-1,pip) && (buf[0] != '\n'))
  513.             fputs(buf,nb);
  514.         fputs(lineshdr,nb);
  515.         fputs(buf,nb);
  516.         while (fgets(buf,sizeof(buf)-1,pip))
  517.             fputs(buf,nb);
  518.     }
  519.     if ((rc=fclose(pip)))
  520.     {
  521.         logerr("$fclose of transport pipe or tmp file returned %d",rc);
  522.     }
  523.     tidyrfc(msg);
  524.     return rc;
  525. }
  526.